import { ESForest } from "../esobjs/ESForest";
import { MyProjectManager } from "../MyProjectManager";
import { Destroyable, react, reactJson, Event, track, bind, HasOwner, createNextAnimateFrameEvent } from "xbsj-xe2/dist-node/xe2-base-utils";
import { ObjResettingWithEvent, SceneObject, Viewer } from 'xbsj-xe2/dist-node/xe2-base-objects';
import { ESMsTileset } from "../esobjs/ESMsTileset";
import axios from "axios";
import { ElMessage } from "element-plus";
import { calculateDistanceInMeters, getRandomElement, getUrlParam } from "../utils";
import { reqCreateMonomer, reqCreateTask, reqDeleteHistory, reqGetHistory, reqGetRandomTile } from "@/api/modelser2Api";
import { GeoPolygon, SceneObjectPickedInfo, getMinMaxCorner } from 'xbsj-xe2/dist-node/xe2-base-objects';
import loading from "@/api/loading";
import { MonomerEdit } from "./monomerEdit";
import { SwitchModelser } from "./switchModelser";

class Modelser2Resettting extends Destroyable {
    constructor(modelser2Manager: Modelser2Manager, owner: MyProjectManager) {
        super();
        modelser2Manager.monomerEdit = new MonomerEdit(owner);
    }
}

export class Modelser2Manager extends HasOwner<MyProjectManager> {

    // 服务路径
    private _modelser2Url = this.dv(react<string>(""));
    get modelser2Url() { return this._modelser2Url.value; }
    get modelser2UrlChanged() { return this._modelser2Url.changed; }
    set modelser2Url(value: string) { this._modelser2Url.value = value; }

    // 是不是Modelser2服务
    private _isModelser2Service = this.dv(react<boolean>(false));
    get isModelser2Service() { return this._isModelser2Service.value; }
    get isModelser2ServiceChanged() { return this._isModelser2Service.changed; }
    set isModelser2Service(value: boolean) { this._isModelser2Service.value = value; }

    // ESMsTileset
    private _eSMsTileset = this.dv(this.owner.createSceneObject(ESMsTileset) as ESMsTileset);
    get eSMsTileset() { return this._eSMsTileset; }

    // 记录列表
    private _recordList = this.dv(react<any>([]));
    get recordList() { return this._recordList.value; }
    get recordListChanged() { return this._recordList.changed; }
    set recordList(value: any) { this._recordList.value = value; }


    // 清除Modelser2窗口
    private _clearModelser2WindowEvent = this.dv(new Event());
    get clearModelser2WindowEvent() { return this._clearModelser2WindowEvent; }


    // 弹出框事件
    private _dialogEvent = this.dv(new Event<[string]>());
    get dialogEvent() { return this._dialogEvent; }

    // 单体化拾取
    private _monomerEdit: undefined | MonomerEdit = undefined;
    get monomerEdit() { return this._monomerEdit; }
    set monomerEdit(value: MonomerEdit | undefined) { this._monomerEdit = value; }

    // 切换modelser服务
    private _switchModelser = this.dv(new SwitchModelser(this.owner));
    get switchModelser() { return this._switchModelser; }

    // 验证是不是Modelser2服务
    async verifyModelser2Service() {
        try {
            // 添加请求头
            const token = localStorage.getItem("Authorization")
            const res2 = await axios({
                url: this.modelser2Url,
                method: 'get',
                headers: {
                    ...(token ? { 'Authorization': token } : {})
                },
            })

            if (res2.data.data && res2.data.data.hasOwnProperty("schema")) {
                this.isModelser2Service = true
                // eSRtsTileset url
                this.eSMsTileset.url = this.modelser2Url
            } else {
                this.isModelser2Service = false
                this.eSMsTileset.url = ""
                ElMessage.error('请输入正确的Modelser服务地址')
            }

        } catch (error) {
            this.isModelser2Service = false
            this.eSMsTileset.url = ""
            ElMessage.error('请输入正确的Modelser服务地址')
            return false
        }

    }


    clear() {
        // 是否是Modelser2服务
        this.isModelser2Service = false
        // 清除Modelser2窗口
        this.clearModelser2WindowEvent.emit()
        // 场景树上的对象删除
        this.owner.modelser2SceneTreeWrapper?.destroyAllSceneObjectTreeItems()
        this.owner.propSceneTree = undefined
    }

    // 设置服务参数
    setServerParam(json: any, serverParam: any) {

        json.forEach((e: any) => {
            // 不是文件夹
            if (e.sceneObj) {
                console.log(e.sceneObj);

                let obj: any = {}
                if (e.sceneObj.type == "ESMsWater") {
                    const points = e.sceneObj.points.map((e: any) => e[2])
                    obj = {
                        srcGeom: e.sceneObj.srcGeom,
                        bottom: Math.min(...points),
                        ceilling: Math.max(...points),
                        absoluteCeilling: true,
                        absoluteBottom: true,
                        textureSize: e.sceneObj.textureSize,
                        textureId: e.sceneObj.textureId,
                        editorType: "patch"
                    }
                } else {
                    obj = {
                        srcGeom: e.sceneObj.srcGeom,
                        bottom: e.sceneObj.bottom,
                        ceilling: e.sceneObj.ceilling,
                        absoluteBottom: e.sceneObj.absoluteBottom,
                        absoluteCeilling: e.sceneObj.absoluteCeilling,
                        editorType: e.sceneObj.operation === '1' ? "clip" : "flatten"
                    }
                }
                serverParam.push(obj)
            }
            // 如果没有子节点，则不执行
            if (e.children && e.children.length > 0) {
                this.setServerParam(e.children, serverParam)
            }
        });

    }

    // 创建裁剪任务
    async createClipTask() {
        try {
            const sceneTree = this.owner.modelser2SceneTreeWrapper?.json.root.children
            const serverParam: any = []

            // 设置服务参数
            this.setServerParam(sceneTree, serverParam)

            const data = {
                "tileservice": this.eSMsTileset.tileServiceName,
                "sceneTree": sceneTree,
                "serverParam": serverParam
            }
            const res = await reqCreateTask(data)
            // @ts-ignore
            if (res.status != 'ok') {
                loading.closeLoading()
                ElMessage({
                    message: "提交失败",
                    type: 'error',
                })
                return;
            }
            loading.closeLoading()
            ElMessage({
                message: "提交成功",
                type: 'success',
            })
            this.owner.modelser2SceneTreeWrapper?.destroyAllSceneObjectTreeItems()
            this.owner.modelser2PropSceneTree = undefined
            this.eSMsTileset.refresh();
        } catch (error) {
            loading.closeLoading()
            ElMessage({
                message: "提交失败",
                type: 'error',
            })
            console.error(error);
        }
    }

    // 随机获取一个Tile的范围
    async getTileRange() {
        try {
            const res = await reqGetRandomTile(this.eSMsTileset.tileServiceName)
            // @ts-ignore
            if (res.status != 'ok') return;
            const features = res.data.features
            const ele = getRandomElement(features)
            const positions = ele.geometry.coordinates[0].map((e: any) => [e[0], e[1], 0])
            // 获取最大最小经纬度坐标
            const { minPos, maxPos } = getMinMaxCorner(positions)
            const distance = calculateDistanceInMeters(minPos[1], minPos[0], maxPos[1], maxPos[0])

            const radius = distance * 1.5 + ele.geometry.maxz
            const rectangle: [number, number, number, number] = [minPos[0], minPos[1], maxPos[0], maxPos[1]]
            this.owner.activeViewer?.flyToBoundingSphere(rectangle, radius)

        } catch (error) {
            console.error(error);
        }
    }

    // 获取编辑历史
    async getRecordlist() {
        try {
            const param = {
                "tileservice": this.eSMsTileset.tileServiceName,
            }
            const res = await reqGetHistory(param)
            // @ts-ignore
            if (res.status != 'ok') return;
            this.recordList = res.data
        } catch (error) {
            console.error(error);
        }
    }

    // 删除编辑历史
    async deleteRecordlist(version: number) {
        try {
            const param = {
                "tileservice": this.eSMsTileset.tileServiceName,
                "version": version
            }
            const res = await reqDeleteHistory(param)
            // @ts-ignore
            if (res.status != 'ok') return;
            loading.closeLoading()
            ElMessage({
                message: "删除成功",
                type: 'success',
            })
            this.eSMsTileset.refresh();
        } catch (error) {
            console.error(error);
        }
    }

    // 创建单体化
    async createMonomer(param: any) {
        try {
            const res = await reqCreateMonomer(param)
            // @ts-ignore
            if (res.status != 'ok') return;
            ElMessage({
                message: "创建单体化成功",
                type: 'success',
            })
        } catch (error) {
            console.error(error);
        }
    }

    constructor(owner: MyProjectManager) {
        super(owner);

        {
            const updata = async (url: string) => {
                // 清除参数
                this.clear()
                if (!url) {
                    this.eSMsTileset.url = ""
                    return;
                }
                // 验证是不是modelser2服务
                await this.verifyModelser2Service()
            }
            this.dispose(this.modelser2UrlChanged.don(updata))
        }
        {
            const obj = getUrlParam();
            this.dispose(this.eSMsTileset.es3DTileset.tilesetReady.disposableOnce(() => {
                if (obj.hasOwnProperty("cameraInfo")) return;
                this.eSMsTileset.es3DTileset.flyTo()
            }))
        }

        {
            const event = this.dv(createNextAnimateFrameEvent(this.modelser2UrlChanged, this.isModelser2ServiceChanged));
            this.dv(new ObjResettingWithEvent(event, () => {
                // cimrts服务地址为空
                if (!this.modelser2Url) return undefined;
                // 不是Cimrts服务
                if (!this.isModelser2Service) return undefined;
                return new Modelser2Resettting(this, this.owner);

            }))
        }
    }
}